﻿#region<<文 件 说 明>>
/*----------------------------------------------------------------
// 文件名称：JsonHelper
// 创 建 者：杨程
// 创建时间：2021/3/4 星期四 16:04:44
// 文件版本：V1.0.0
// ===============================================================
// 功能描述：
//
//
//----------------------------------------------------------------*/
#endregion

namespace Vampirewal.Core;

/// <summary>
/// JSON帮助类
/// </summary>
public class JsonHelper
{
    /// <summary>
    /// json字符串格式化输出
    /// </summary>
    /// <param name="sourceJsonStr"></param>
    /// <returns></returns>
    public static string FormatJsonString(string sourceJsonStr)
    {
        //格式化json字符串
        JsonSerializer serializer = new JsonSerializer();
        TextReader tr = new StringReader(sourceJsonStr);
        JsonTextReader jtr = new JsonTextReader(tr);
        object obj = serializer.Deserialize(jtr);
        if (obj != null)
        {
            StringWriter textWriter = new StringWriter();
            JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)
            {
                Formatting = Formatting.Indented,
                Indentation = 4,
                IndentChar = ' '
            };
            serializer.Serialize(jsonWriter, obj);
            return textWriter.ToString();
        }
        else
        {
            return sourceJsonStr;
        }
    }

    /// <summary>
    /// 将object对象转换为实体对象
    /// </summary>
    /// <typeparam name="T">实体对象类名</typeparam>
    /// <param name="asObject">object对象</param>
    /// <returns></returns>
    public static T ConvertObject<T>(object asObject) where T : new()
    {
        //var serializer = new JavaScriptSerializer();
        string strJson = JsonConvert.SerializeObject(asObject);
        //将object对象转换为json字符
        //var json = serializer.Serialize(asObject);
        //将json字符转换为实体对象
        var t = JsonConvert.DeserializeObject<T>(strJson);
        return t;
    }

    /// <summary>
    /// 将实体类转化为json格式
    /// </summary>
    /// <typeparam name="T">实体类</typeparam>
    /// <param name="entity">实体</param>
    /// <param name="IsFormat">是否格式化</param>
    /// <returns></returns>
    public static string SerializeObjectToJson<T>(T entity, bool IsFormat = false)
    {
        string json = JsonConvert.SerializeObject(entity);
        if (IsFormat)
        {
            return FormatJsonString(json);
        }
        else
        {
            return json;
        }
    }

    /// <summary>
    /// 读取指定目录下的JSON文件
    /// </summary>
    /// <returns>JSON文件中的value值</returns>
    public static string Readjson(string JsonPath)
    {
        using (System.IO.StreamReader sr = System.IO.File.OpenText(JsonPath))
        {
            string json = sr.ReadToEnd();

            return json;
        }
    }

    /// <summary>
    /// 读取指定目录下的JSON文件并转换对应的类型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="JsonPath"></param>
    /// <returns></returns>
    public static T ReadJsonToEntity<T>(string JsonPath)
    {
        using (System.IO.StreamReader sr = System.IO.File.OpenText(JsonPath))
        {
            string json = sr.ReadToEnd();

            var result= JsonConvert.DeserializeObject<T>(json);

            return result??default;
        }
    }

    /// <summary>
    /// 获取相应子节点的值
    /// </summary>
    public static string JSON_SeleteNode(JToken json, string ReName)
    {
        try
        {
            string result = "";
            //这里6.0版块可以用正则匹配
            var node = json.SelectToken("$.." + ReName);
            if (node != null)
            {
                //判断节点类型
                if (node.Type == JTokenType.String || node.Type == JTokenType.Integer || node.Type == JTokenType.Float)
                {
                    //返回string值
                    result = node.Value<object>().ToString();
                }
            }
            return result;
        }
        catch (Exception ex)
        {
            return "";
        }
    }

    /// <summary>
    /// 遍历所以节点，替换其中某个节点的值
    /// </summary>
    /// <param name="jobj">json数据</param>
    /// <param name="nodeName">节点名</param>
    /// <param name="value">新值</param>
    public static void JSON_SetChildNodes(ref JToken jobj, string nodeName, string value)
    {
        try
        {
            JToken result = jobj as JToken;//转换为JToken
            JToken result2 = result.DeepClone();//复制一个返回值，由于遍历的时候JToken的修改回终止遍历，因此需要复制一个新的返回json
                                                //遍历
            var reader = result.CreateReader();
            while (reader.Read())
            {
                if (reader.Value != null)
                {
                    if (reader.TokenType == JsonToken.String || reader.TokenType == JsonToken.Integer || reader.TokenType == JsonToken.Float)
                    {
                        Regex reg = new Regex(@"" + nodeName + "$");
                        //SelectToken(Path)方法可查找某路径下的节点，在Newtonsoft.Json 4.5 版本中不可使用正则匹配，在6.0版本中可用使用，会方便很多，6.0版本下替换值会更方便，这个需要特别注意的
                        if (reg.IsMatch(reader.Path))
                        {
                            result2.SelectToken(reader.Path).Replace(value);
                        }
                    }
                }
            }
            jobj = result2;
        }
        catch 
        {
        }
    }
}